package cn.walls1717.wallsmall.search.thread;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 测试CompletableFuture
 * 
 * @author walls1717
 * @since 2022/11/08 20:10
 **/
@Slf4j
public class ThreadTest5 {
    private static final ExecutorService executor = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        log.info("main -> start");
        /*CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            log.info("当前线程id -> {}", Thread.currentThread().getId());
            int i = 10 / 2;
            log.info("运行结果 -> {}", i);
        }, executor);*/
        /*CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            log.info("当前线程id -> {}", Thread.currentThread().getId());
            int i = 10 / 2;
            log.info("运行结果 -> {}", i);
            return i;
        }, executor).whenComplete((result, exception) -> {
            log.info("结果是 -> {}，异常是 -> {}", result, exception);
        });*/
        // Integer integer = future.get();

        /*
         线程串行化(有Async后缀的是新开一个线程执行任务，无此后缀的是两个任务公用一个线程)：
         1.thenRun：不能获取到上一步的执行结果，无返回值。
         2.thenAcceptAsync：能接收到上一步的返回结果，但是无返回值。
         */
        /*
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            log.info("当前线程id -> {}", Thread.currentThread().getId());
            int i = 10 / 2;
            log.info("运行结果 -> {}", i);
            return i;
        }, executor).thenApplyAsync(res -> {
            log.info("任务2启动，线程id -> {}", Thread.currentThread().getId());
            return "任务2结果就是我，任务1结果 -> " + res;
        }, executor);
        
        String s = future.get();
        log.info("future -> {}", s);
        */

        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            log.info("任务1线程id -> {}", Thread.currentThread().getId());
            int i = 10 / 2;
            log.info("任务1运行结果 -> {}", i);
            return i;
        }, executor);

        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            log.info("任务2线程id -> {}", Thread.currentThread().getId());
            log.info("任务2结束");
            return "hello";
        }, executor);

        /*future1.runAfterBothAsync(future2, ()->{
            log.info("任务3开始");
        }, executor);*/

        /*future1.thenAcceptBothAsync(future2, (f1, f2)->{
            log.info("任务1结果 -> {}，任务2结果 -> {}", f1, f2);
        }, executor);*/

        future1.runAfterEitherAsync(future2, () -> {
            log.info("任务3");
        }, executor);

        log.info("main -> end");
    }
}
